package com.pan.api.convert.impl;


import com.pan.api.anno.PanComment;
import com.pan.api.convert.MethodStrategy;
import com.pan.api.convert.ArgumentStrategy;
import com.pan.api.entity.ArgumentInformation;
import com.pan.api.entity.MethodInformation;
import org.springframework.web.bind.annotation.*;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MethodStrategyImpl
        extends MethodStrategy {
    public MethodStrategyImpl(ArgumentStrategy argumentStrategy) {
        super(argumentStrategy);
    }

    @Override
    public List<MethodInformation> handle(Class clazz) {
        List<MethodInformation> resultList = new ArrayList<>();
        Method[] methods = clazz.getMethods();
        for (Method method: methods){
            if (method.getAnnotations().length == 0) continue;
            Annotation annotation;
            RequestMethod[] types;
            String[] path;
            if ((annotation = method.getAnnotation(RequestMapping.class))!= null){
                RequestMapping reqMap = (RequestMapping) annotation;
                path = reqMap.value();
                types = reqMap.method();
                if (types.length == 0){
                    types = RequestMethod.values();
                }
            }else if ((annotation = method.getAnnotation(GetMapping.class))!= null){
                types = new RequestMethod[]{RequestMethod.GET};
                GetMapping reqMap = (GetMapping) annotation;
                path = reqMap.value();
            }else if ((annotation = method.getAnnotation(PostMapping.class))!= null){
                types = new RequestMethod[]{RequestMethod.POST};
                PostMapping reqMap = (PostMapping) annotation;
                path = reqMap.value();
            }else if ((annotation = method.getAnnotation(PutMapping.class))!= null){
                types = new RequestMethod[]{RequestMethod.PUT};
                PutMapping reqMap = (PutMapping) annotation;
                path = reqMap.value();
            }else if ((annotation = method.getAnnotation(DeleteMapping.class))!= null){
                types = new RequestMethod[]{RequestMethod.DELETE};
                DeleteMapping reqMap = (DeleteMapping) annotation;
                path = reqMap.value();
            } else {
                continue;
            }
            MethodInformation methodInformation = new MethodInformation();
            String[] typesStrArr = new String[types.length];
            for (int i = 0; i < types.length; i++) {
                typesStrArr[i] = types[i].name();
            }
            methodInformation.setRequestType(typesStrArr);
            methodInformation.setUrl(path.length == 1?path[0]: Arrays.toString(path));
            if (method.getAnnotation(ResponseBody.class)!=null){
                methodInformation.setJsonXml(true);
            }else {
                methodInformation.setJsonXml(false);
            }
            if ((annotation = method.getAnnotation(PanComment.class))!= null){
                String value = ((PanComment) annotation).value();
                methodInformation.setComment(value);
            }else {
                methodInformation.setComment("");
            }
//            Class<?> returnType = method.getReturnType();
//            returnType.getGenericInterfaces();
            methodInformation.setReturnType( method.getReturnType());
            methodInformation.setMethodName( method.getName());
            List<ArgumentInformation> argumentInformationList = super.argumentStrategy.handle(method);
            methodInformation.setArgList(argumentInformationList);
            resultList.add(methodInformation);
        }
        return resultList;
    }
}
